#region File Description
//-----------------------------------------------------------------------------
// LoadingScreen.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;
#endregion

namespace Alex_s_Dream_The_Toy_World
{
    /// <summary>
    /// The loading screen coordinates transitions between the menu system and the
    /// game itself. Normally one screen will transition off at the same time as
    /// the next screen is transitioning on, but for larger transitions that can
    /// take a longer time to load their data, we want the menu system to be entirely
    /// gone before we start loading the game. This is done as follows:
    /// 
    /// - Tell all the existing screens to transition off.
    /// - Activate a loading screen, which will transition on at the same time.
    /// - The loading screen watches the state of the previous screens.
    /// - When it sees they have finished transitioning off, it activates the real
    ///   next screen, which may take a long time to load its data. The loading
    ///   screen will be the only thing displayed while this load is taking place.
    /// </summary>
    class LoadingScreen : GameScreen
    {
        #region Fields

        bool loadingIsSlow;
        bool otherScreensAreGone;
        ContentManager content;
        Texture2D[] toyWorld;
        KeyboardState keyState, PreKeyState;
        int state = 0;
        bool start = false;
        bool pressEnter = false;
        bool pressBack = false;
        GameScreen[] screensToLoad;

        #endregion

        #region Initialization

        
        /// <summary>
        /// The constructor is private: loading screens should
        /// be activated via the static Load method instead.
        /// </summary>
        private LoadingScreen(ScreenManager screenManager, bool loadingIsSlow,
                              GameScreen[] screensToLoad)
        {
            this.loadingIsSlow = loadingIsSlow;
            this.screensToLoad = screensToLoad;

            TransitionOnTime = TimeSpan.FromSeconds(0.5);
        }

        public override void LoadContent(ContentManager contentManager)
        {
            if (contentManager == null)
                content = new ContentManager(ScreenManager.Game.Services, "Content");
            else
                content = contentManager;

            toyWorld = new Texture2D[8];
            toyWorld[0] = content.Load<Texture2D>("Menu/" + "hatetoy");
            toyWorld[1] = content.Load<Texture2D>("Menu/" + "toychess");
            toyWorld[2] = content.Load<Texture2D>("Menu/" + "mum");
            toyWorld[3] = content.Load<Texture2D>("Menu/" + "sleep");
            toyWorld[4] = content.Load<Texture2D>("Menu/" + "fairyworld");
            toyWorld[5] = content.Load<Texture2D>("Menu/" + "angel");
            toyWorld[6] = content.Load<Texture2D>("Menu/" + "angrytoy");
        }
        /// <summary>
        /// Activates the loading screen.
        /// </summary>
        public static void Load(ScreenManager screenManager, bool loadingIsSlow, params GameScreen[] screensToLoad)
        {
            // Tell all the current screens to transition off.
            //foreach (GameScreen screen in screenManager.GetScreens())
                //screen.ExitScreen();

            // Create and activate the loading screen.
            LoadingScreen loadingScreen = new LoadingScreen(screenManager,
                                                            loadingIsSlow,
                                                            screensToLoad);

            screenManager.AddScreen(loadingScreen);
        }


        #endregion

        #region Update and Draw


        /// <summary>
        /// Updates the loading screen.
        /// </summary>
        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
            PreKeyState = keyState;
            keyState = Keyboard.GetState();
            if (state < 7 && (keyState.IsKeyDown(Keys.Right) && PreKeyState.IsKeyUp(Keys.Right) || keyState.IsKeyDown(Keys.Down) && PreKeyState.IsKeyUp(Keys.Down) || (pressEnter  && keyState.IsKeyDown(Keys.Enter) && PreKeyState.IsKeyUp(Keys.Enter))))
            {
                if (state == 6)
                {
                    start = true;
                }
                else
                    state++;
            }
            if (state > -1 && (keyState.IsKeyDown(Keys.Back) && PreKeyState.IsKeyUp(Keys.Back) || keyState.IsKeyDown(Keys.Left) && PreKeyState.IsKeyUp(Keys.Left) || keyState.IsKeyDown(Keys.Up) && PreKeyState.IsKeyUp(Keys.Up)))
            {
                if (state == 0)
                {
                    pressBack = true;
                }
                else
                    state--;
            }
            if (keyState.IsKeyDown(Keys.Escape) || (pressBack && keyState.IsKeyDown(Keys.Back)))
            {
                ExitScreen();
            }
            // If all the previous screens have finished transitioning
            // off, it is time to actually perform the load.
            if (start)
            {
                foreach (GameScreen screen in ScreenManager.GetScreens())
                    screen.ExitScreen();
                //if (otherScreensAreGone)
                {
                    ScreenManager.RemoveScreen(this);

                    foreach (GameScreen screen in screensToLoad)
                    {
                        if (screen != null)
                        {
                            ScreenManager.AddScreen(screen);
                        }
                    }

                    // Once the load has finished, we use ResetElapsedTime to tell
                    // the  game timing mechanism that we have just finished a very
                    // long frame, and that it should not try to catch up.
                    ScreenManager.Game.ResetElapsedTime();
                }
            }
        }


        /// <summary>
        /// Draws the loading screen.
        /// </summary>
        public override void Draw(GameTime gameTime)
        {
            // If we are the only active screen, that means all the previous screens
            // must have finished transitioning off. We check for this in the Draw
            // method, rather than in Update, because it isn't enough just for the
            // screens to be gone: in order for the transition to look good we must
            // have actually drawn a frame without them before we perform the load.
            if ((ScreenState == ScreenState.Active) &&
                (ScreenManager.GetScreens().Length == 1))
            {
                otherScreensAreGone = true;
            }

            // The gameplay screen takes a while to load, so we display a loading
            // message while that is going on, but the menus load very quickly, and
            // it would look silly if we flashed this up for just a fraction of a
            // second while returning from the game to the menus. This parameter
            // tells us how long the loading is going to take, so we know whether
            // to bother drawing the message.
            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
            Viewport viewport = ScreenManager.Game.GraphicsDevice.Viewport;
            Rectangle fullscreen = new Rectangle(0, 0, viewport.Width, viewport.Height);
            byte fade = TransitionAlpha;
            spriteBatch.Begin(); 
            spriteBatch.Draw(toyWorld[state], fullscreen, new Color(fade, fade, fade));
            pressEnter = true;
            spriteBatch.End();
        }


        #endregion
    }
}
